package cn.com.nes.site.service.monitor.impl;

import cn.com.nes.mybatis.agent.ope.entity.IsEquipmentInfo;
import cn.com.nes.mybatis.agent.ope.entity.IsInstallInfo;
import cn.com.nes.mybatis.agent.ope.entity.IsWxsb;
import cn.com.nes.mybatis.agent.ope.mapper.IsInstallInfoMapper;
import cn.com.nes.mybatis.callcenter.entity.CcUser;
import cn.com.nes.mybatis.callcenter.entity.WorkOrderInfo;
import cn.com.nes.site.entity.bo.workorder.SaveInstallInfoBO;
import cn.com.nes.site.entity.em.InstallPictureEnum;
import cn.com.nes.site.entity.vo.workOrder.SaveWorkOrderInstallPicVO;
import cn.com.nes.site.service.crm.customer.CrmCustomerService;
import cn.com.nes.site.service.crm.customer.CustomerHouseService;
import cn.com.nes.site.service.crm.customer.dto.CustomerDTO;
import cn.com.nes.site.service.crm.customer.dto.CustomerHouseDTO;
import cn.com.nes.site.service.iot.IotDtuService;
import cn.com.nes.site.service.monitor.EquipmentService;
import cn.com.nes.site.service.monitor.IsInstallInfoService;
import cn.com.nes.site.service.monitor.dto.EquipmentInfoDTO;
import cn.com.nes.site.service.system.dict.TParamService;
import cn.com.nes.site.service.system.ope.OpeService;
import cn.com.nes.site.service.system.user.CcUserService;
import cn.com.nes.site.service.workOrder.CallWorkOrderInfoService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备安装信息实现
 *
 * @Author: ShenWei
 * @Date: 2024/06/20/9:53
 */
@Service
@Slf4j
public class IsInstallInfoServiceImpl extends ServiceImpl<IsInstallInfoMapper, IsInstallInfo> implements IsInstallInfoService {

    @Resource
    private CallWorkOrderInfoService callWorkOrderInfoService;

    @Resource
    private CcUserService ccUserService;

    @Resource
    private CrmCustomerService crmCustomerService;

    @Resource
    private CustomerHouseService customerHouseService;

    @Resource
    private EquipmentService equipmentService;

    @Resource
    private IotDtuService iotDtuService;

    @Resource
    private OpeService opeService;

    @Resource
    private TParamService tParamService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveInstallInfo(SaveInstallInfoBO bo) throws Exception {
        Long workOrderId = bo.getWorkOrderId();
        if (ObjectUtil.isNull(workOrderId)) {
            throw new Exception("保存安装信息,工单id不能为空!");
        }

        // 查询工单信息
        WorkOrderInfo workOrderInfo = bo.getWorkOrderInfo();
        if (ObjectUtil.isNull(workOrderInfo)) {
            workOrderInfo = callWorkOrderInfoService.selectByPrimaryKey(workOrderId);
            if (ObjectUtil.isNull(workOrderInfo)) {
                throw new Exception("未查询到安装工单信息,安装工单id:" + workOrderId);
            }
        }
        // 判断房屋信息绑定情况
        if (ObjectUtil.isNull(workOrderInfo.getCustomerHouseId())) {
            throw new Exception("当前安装工单未绑定客户的房屋信息,保存安装信息失败");
        }
        // 查询工单安装的房屋信息
        CustomerHouseDTO houseInfo = customerHouseService.getHouseDetail(workOrderInfo.getCustomerHouseId());
        if (ObjectUtil.isNull(houseInfo) || StrUtil.isBlank(houseInfo.getHouseUuid())) {
            throw new Exception("房屋信息不存在或缺失业务id");
        }
        // 查询历史安装信息
        QueryWrapper<IsInstallInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("dd_id", houseInfo.getHouseUuid());
        IsInstallInfo isInstallInfo = this.getOne(wrapper);
        if (ObjectUtil.isNull(isInstallInfo)) {
            isInstallInfo = new IsInstallInfo();
            isInstallInfo.setCjsj(bo.getOperateDate());
        }

        // 查询安装人信息
        CcUser handleUserInfo = bo.getHandleUserInfo();
        if (ObjectUtil.isNull(handleUserInfo)) {
            handleUserInfo = ccUserService.getCcUser(workOrderInfo.getMaintainId());
        }
        // 查询工单所属客户信息
        CustomerDTO customerInfo = crmCustomerService.getCustomerById(workOrderInfo.getCustomerId());
        // 获取图片信息
        List<SaveWorkOrderInstallPicVO> savePicList = bo.getSavePicList();


        // 组装参数
        isInstallInfo.setKhId(workOrderInfo.getCustomerId());
        isInstallInfo.setScddh(String.valueOf(workOrderInfo.getSaleOrderId()));
        isInstallInfo.setZbq(StrUtil.isNotBlank(workOrderInfo.getQualityGuaranteeYears()) ? Long.valueOf(workOrderInfo.getQualityGuaranteeYears()) : null);
        isInstallInfo.setAzsgrq(workOrderInfo.getInstallDate());
        isInstallInfo.setAzwcrq(workOrderInfo.getInstallDate());
        isInstallInfo.setLxdh(workOrderInfo.getContactPhone());
        isInstallInfo.setXmlxr(workOrderInfo.getContact());
        isInstallInfo.setXmlxrdh(workOrderInfo.getContactPhone());
        isInstallInfo.setXmdz(workOrderInfo.getAddress());
        // 处理质保日期 安装日期 + 质保期
        if (ObjectUtil.isNotNull(workOrderInfo.getGmtModified()) && ObjectUtil.isNotNull(isInstallInfo.getZbq())) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(workOrderInfo.getGmtModified())); // 格式化安装日期
            calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + Math.toIntExact(isInstallInfo.getZbq())); // 组装新日期
            isInstallInfo.setZbrq(calendar.getTime());
        }
        // 组装安装人相关字段
        if (ObjectUtil.isNotNull(handleUserInfo)) {
            isInstallInfo.setTsr(handleUserInfo.getName());
            isInstallInfo.setTsrdh(handleUserInfo.getPhone());
        }
        // 组装客户相关字段
        if (ObjectUtil.isNotNull(customerInfo)) {
            isInstallInfo.setSfzh(customerInfo.getIdCardNumber());
            isInstallInfo.setKhbh(customerInfo.getCustomerCode());
            isInstallInfo.setBz(customerInfo.getMemo());
            isInstallInfo.setYnztxz(customerInfo.getEnergyUseProperty());
            isInstallInfo.setYzxm(customerInfo.getCustomerName());
        }
        // 组装房屋相关字段
        isInstallInfo.setDdId(houseInfo.getHouseUuid());  // 2024-06 项目组决定将地点id定义为房屋业务id
        isInstallInfo.setXzqh(houseInfo.getAreaCode());
        isInstallInfo.setMph(houseInfo.getHouseNumber());
        isInstallInfo.setDbh(houseInfo.getElectricityMeterNumbers());
        isInstallInfo.setJzcg(ObjectUtil.isNotNull(houseInfo.getBuildingHeight()) ? String.valueOf(houseInfo.getBuildingHeight()) : StrUtil.EMPTY);
        isInstallInfo.setJzmj(ObjectUtil.isNotNull(houseInfo.getFloorSpace()) ? String.valueOf(houseInfo.getFloorSpace()) : StrUtil.EMPTY);
        isInstallInfo.setJzjg(houseInfo.getBuildingStructureName());
        isInstallInfo.setCnmj(houseInfo.getHeatingArea());
        isInstallInfo.setCnmd(houseInfo.getHeatingEndName());
        isInstallInfo.setWqbw(ObjectUtil.isNotNull(houseInfo.getOuterWallKeepWarm()) && houseInfo.getOuterWallKeepWarm() ? "有" : " 无");
//        isInstallInfo.setWqbw(StrUtil.isBlank(houseInfo.getOuterWallKeepWarm()) ? "无" : tParamService.getNameByParamTypeAndValue("332", houseInfo.getOuterWallKeepWarm()));
        isInstallInfo.setJzazwz(houseInfo.getInstallPositionName());
        isInstallInfo.setJd(bo.getLongitude());
        isInstallInfo.setWd(bo.getLatitude());
        isInstallInfo.setSjfh(houseInfo.getDesignHeatingLoad());
        isInstallInfo.setEnergyType(houseInfo.getEnergyTypeName());
        isInstallInfo.setHeatingArea(houseInfo.getHeatingArea());
        isInstallInfo.setBuiltArea(houseInfo.getFloorSpace());
        // 外墙厚度有点特殊，是个字典值，可能出现用户配置的外墙厚度字典包含非数字字符
        BigDecimal outerWallThickness = null;
        try {
            if (ObjectUtil.isNotNull(houseInfo.getOuterWallThicknessName())) {
                outerWallThickness = new BigDecimal(houseInfo.getOuterWallThicknessName());
            }
        } catch (Exception e) {
            outerWallThickness = BigDecimal.ZERO;
        } finally {
            isInstallInfo.setWqhd(outerWallThickness);
        }
        // 处理图片信息
        if (CollectionUtil.isNotEmpty(savePicList)) {
            List<String> installPicList = new ArrayList<>();
            for (SaveWorkOrderInstallPicVO picDetail : savePicList) {
                if (ObjectUtil.isNotNull(picDetail) && StrUtil.isNotBlank(picDetail.getField())) {
                    if (InstallPictureEnum.PLAN_VIEW.getKey().equals(picDetail.getField())) {
                        isInstallInfo.setPmt(picDetail.getPath());
                    } else if (InstallPictureEnum.DESIGN.getKey().equals(picDetail.getField())) {
                        isInstallInfo.setSjt(picDetail.getPath());
                    } else {
                        installPicList.add(picDetail.getPath());
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(installPicList)) {
                isInstallInfo.setImages(String.join(";", installPicList));
            }
        }
        // 组装其他字段
        isInstallInfo.setType(2);           // 先默认为户用
        isInstallInfo.setSjly("agent");     // 默认 agent
        isInstallInfo.setAuditState("1");   // 默认审核通过
        isInstallInfo.setBelongTo(bo.getUserInfo().getNes_companyId());
        isInstallInfo.setManufactureId(bo.getUserInfo().getNes_companyId());
        isInstallInfo.setSfsc(0);
        isInstallInfo.setXgsj(bo.getOperateDate());
        // 罗列一些拿不到值的字段,将来如果有值了方便寻找
/*        isInstallInfo.setHtbh(null);
        isInstallInfo.setAzxy(null);
        isInstallInfo.setXyId(null);
        isInstallInfo.setSjjy(null);
        isInstallInfo.setCzrs(null);
        isInstallInfo.setScsl(null);
        isInstallInfo.setCssbsl(null);
        isInstallInfo.setXbcs(null);
        isInstallInfo.setFhrq(null);
        isInstallInfo.setV1(null);
        isInstallInfo.setXmnr(null);
        isInstallInfo.setRytazwz(null);
        isInstallInfo.setJzgn(null);
        isInstallInfo.setKtxtgn(null);
        isInstallInfo.setRzb(null);
        isInstallInfo.setDesignUnits(null);
        isInstallInfo.setActualUnits(null);
        isInstallInfo.setProjectType(null);
        isInstallInfo.setXmmc(null);
        isInstallInfo.setXmjc(workOrderInfo.getWorkOrderName());
        isInstallInfo.setXmbh(String.valueOf(workOrderInfo.getId()));*/

        this.saveOrUpdate(isInstallInfo);
        saveEquipmentInfo(workOrderId, isInstallInfo);
        return isInstallInfo.getId();
    }

    // 更新设备信息
    private void saveEquipmentInfo(Long workOrderId, IsInstallInfo isInstallInfo) throws Exception {
        // 查询工单下设备列表
        List<EquipmentInfoDTO> equipmentInfoList = equipmentService.getEquipmentInfoListByWorkOrderId(workOrderId);

        if (CollectionUtil.isNotEmpty(equipmentInfoList)) {
            for (EquipmentInfoDTO item : equipmentInfoList) {
                if (ObjectUtil.isNull(item)) continue;

                IsEquipmentInfo equipmentInfo = new IsEquipmentInfo();
                IsWxsb dtu = iotDtuService.getDtu(item.getWxId());
                if (ObjectUtil.isNotNull(dtu)) {
                    equipmentInfo.setProtocolId(dtu.getProtocolId());
                }
                // 更新设备的质保日期
                equipmentInfo.setId(item.getId());
                equipmentInfo.setSbId(item.getSbId());
                equipmentInfo.setZbq(isInstallInfo.getZbrq());
                equipmentInfo.setJd(isInstallInfo.getJd());
                equipmentInfo.setWd(isInstallInfo.getWd());
                equipmentInfo.setBz("安装工单完成生成设备");
                Integer rows = equipmentService.saveEquipmentInfo(equipmentInfo);

                if (ObjectUtil.isNull(rows) || rows != 1) {
                    log.error("保存设备信息异常,设备id:" + item.getSbId());
                }
            }

            // 更新Dtu版本号和采集模块总版本号
            try {
                Set<String> dtuIdSet = equipmentInfoList.stream()
                        .filter(ObjectUtil::isNotNull)
                        .map(EquipmentInfoDTO::getWxId)
                        .collect(Collectors.toSet());
//                iotDtuService.updateDtuVersion(dtuIdList);

                // 2024-08-16 切换为离线DTU方式刷新版本号
                opeService.restartDtu(dtuIdSet);
            } catch (Exception e) {
                log.error("更新无线设备版本号失败,失败原因:", e);
            }
        }
    }
}
